﻿//PlazaTableManager.cs
//Copyright (c) 2013 StockSharp LLC, all rights reserved.
//This code module is part of StockSharp library.
//This code is licensed under the GNU GENERAL PUBLIC LICENSE Version 3.
//See the file License.txt for the license details.
//More info on: http://stocksharp.com

namespace StockSharp.Plaza
{
	using System;
	using System.Linq;

	using Ecng.Collections;
	using Ecng.Common;

	using StockSharp.Logging;
	using StockSharp.Plaza.Metadata;

	class PlazaTableManager
	{
		private readonly PlazaTrader _trader;

		public PlazaTableManager(PlazaTrader trader)
		{
			if (trader == null)
				throw new ArgumentNullException("trader");

			_trader = trader;

			var tableRegistry = _trader.TableRegistry;
			var streamRegistry = tableRegistry.StreamRegistry;

			streamRegistry.AllStreams.ForEach(s => s.Log += OnStreamLog);

			DefaultFutureDepthTable = tableRegistry.Aggregation5Future;
			DefaultOptionDepthTable = tableRegistry.Aggregation5Option;

			_trader.Tables.AddRange(tableRegistry.DefaultTables);

			var groupping = _trader.StreamManager.ConnectionGroupping;

			groupping[streamRegistry.Aggregation5Future] = 0;
			groupping[streamRegistry.Aggregation5Option] = 0;
			groupping[streamRegistry.Aggregation20Future] = 0;
			groupping[streamRegistry.Aggregation20Option] = 0;
			groupping[streamRegistry.Aggregation50Future] = 0;
			groupping[streamRegistry.Aggregation50Option] = 0;

			groupping[streamRegistry.TradeFuture] = 1;
			groupping[streamRegistry.TradeOption] = 1;

			groupping[streamRegistry.OrdersLog] = 2;

			groupping[streamRegistry.Index] = 3;
			groupping[streamRegistry.IndexLog] = 3;

			groupping[streamRegistry.McxCommonCurrency] = 4;
			groupping[streamRegistry.McxCommonSpot] = 4;
			groupping[streamRegistry.McxInfoCurrency] = 4;
			groupping[streamRegistry.McxInfoSpot] = 4;
			groupping[streamRegistry.McxTradesCurrency] = 5;
			groupping[streamRegistry.McxTradesSpot] = 5;
			groupping[streamRegistry.McxAggrCurrency] = 6;
			groupping[streamRegistry.McxAggrSpot] = 6;
		}

		private void OnStreamLog(PlazaStream stream, string message)
		{
			_trader.AddInfoLog(() => "PlazaStream {0}:{1}".Put(stream.Name, message));
		}

		private PlazaTable _defaultFutureDepthTable;

		public PlazaTable DefaultFutureDepthTable
		{
			get { return _defaultFutureDepthTable ?? (_defaultFutureDepthTable = _trader.Tables.FirstOrDefault(t => _trader.TableRegistry.AggregationFutures.Contains(t))); }
			set
			{
				if (value != null && !_trader.TableRegistry.AggregationFutures.Contains(value))
					throw new ArgumentException("{0} не является потоком агрегированных стаканов фьючерсов.".Put(value));

				if (_defaultFutureDepthTable == value)
					return;

				if (_defaultFutureDepthTable != null)
					_trader.Tables.Remove(_defaultFutureDepthTable);

				_defaultFutureDepthTable = value;

				if (value != null)
					_trader.Tables.Add(value);
			}
		}

		private PlazaTable _defaultOptionDepthTable;

		public PlazaTable DefaultOptionDepthTable
		{
			get { return _defaultOptionDepthTable ?? (_defaultOptionDepthTable = _trader.Tables.FirstOrDefault(t => _trader.TableRegistry.AggregationOptions.Contains(t))); }
			set
			{
				if (value != null && !_trader.TableRegistry.AggregationOptions.Contains(value))
					throw new ArgumentException("{0} не является потоком агрегированных стаканов опционов.".Put(value));

				if (_defaultOptionDepthTable == value)
					return;

				if (_defaultOptionDepthTable != null)
					_trader.Tables.Remove(_defaultOptionDepthTable);

				_defaultOptionDepthTable = value;

				if (value != null)
					_trader.Tables.Add(value);
			}
		}

		private bool _createTradesFromOrdersLog;

		public bool CreateTradesFromOrdersLog
		{
			get { return _createTradesFromOrdersLog; }
			set
			{
				if (_createTradesFromOrdersLog == value)
					return;

				_createTradesFromOrdersLog = value;

				if (value)
				{
					_trader.Tables.Add(_trader.TableRegistry.AnonymousOrdersLog);

					_trader.Tables.Remove(_trader.TableRegistry.TradeFuture);
					_trader.Tables.Remove(_trader.TableRegistry.TradeOption);
				}
				else
					_trader.Tables.Remove(_trader.TableRegistry.AnonymousOrdersLog);
			}
		}

		private bool _createDepthFromOrdersLog;

		public bool CreateDepthFromOrdersLog
		{
			get { return _createDepthFromOrdersLog; }
			set
			{
				if (_createDepthFromOrdersLog == value)
					return;

				_createDepthFromOrdersLog = value;

				if (value)
				{
					_trader.Tables.Add(_trader.TableRegistry.AnonymousOrdersLog);

					DefaultFutureDepthTable = null;
					DefaultOptionDepthTable = null;
				}
				else
					_trader.Tables.Remove(_trader.TableRegistry.AnonymousOrdersLog);
			}
		}
	}
}